package org.bukkitmodders.copycat.managers;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import javax.xml.bind.JAXB;

import org.apache.commons.io.IOUtils;
import org.bukkit.entity.Player;
import org.bukkitmodders.copycat.schema.GlobalSettingsType.ProhibitedWorlds;
import org.bukkitmodders.copycat.schema.ObjectFactory;
import org.bukkitmodders.copycat.schema.PlayerSettingsType;
import org.bukkitmodders.copycat.schema.PluginConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ConfigurationManager {

	private static final String DATAFILE = "pluginSettings.xml";
	private Logger log = LoggerFactory.getLogger(ConfigurationManager.class);

	private final File dataFolder;
	private final PluginConfig pluginConfig;
	private final ObjectFactory of = new ObjectFactory();

	public ConfigurationManager(File dataFolder) {

		this.dataFolder = dataFolder;
		PluginConfig pluginConfig = JAXB.unmarshal(getDataFile(), PluginConfig.class);
		this.pluginConfig = pluginConfig;

		log.info("Loaded Config File: " + getDataFile().getAbsolutePath());
	}

	public PlayerSettingsManager getPlayerSettings(Player requestingPlayer, String targetPlayerName) {

		List<PlayerSettingsType> playerPreferences = pluginConfig.getPreferences().getPlayerPreferences();

		PlayerSettingsType toReturn = null;

		for (PlayerSettingsType playerSettings : playerPreferences) {
			if (playerSettings.getPlayerName().equalsIgnoreCase(targetPlayerName)) {
				toReturn = playerSettings;
				break;
			}
		}

		if (toReturn == null) {
			// Player has no settings. Make a new one.
			toReturn = of.createPlayerSettingsType();
			toReturn.setPlayerName(targetPlayerName);
			toReturn.setPlayerEnabled(true);
			toReturn.setShortcuts(of.createPlayerSettingsTypeShortcuts());
			playerPreferences.add(toReturn);

			persist();
		}

		return new PlayerSettingsManager(toReturn, requestingPlayer, this);
	}

	synchronized void persist() {
		JAXB.marshal(pluginConfig, getDataFile());
	}

	public File getDataFile() {

		if (!dataFolder.exists()) {
			dataFolder.mkdir();
		}

		File dataFile = new File(dataFolder.getAbsoluteFile() + File.separator + DATAFILE);

		if (!dataFile.exists()) {
			createDefaultConfig(dataFile);
		}

		return dataFile;
	}

	private void createDefaultConfig(File dataFile) {

		InputStream in = null;
		OutputStream out = null;

		try {
			dataFile.createNewFile();

			in = getClass().getResourceAsStream("/defaultSettings.xml");
			out = new FileOutputStream(dataFile);

			IOUtils.copy(in, out);

		} catch (IOException e) {
			log.error("Error creating default configuration.", e);
		} finally {
			IOUtils.closeQuietly(in);
			IOUtils.closeQuietly(out);
		}
	}

	public boolean isWorldEnabled(String name) {

		List<String> worlds = pluginConfig.getGlobalSettings().getProhibitedWorlds().getWorld();

		if (worlds.contains(name)) {
			return false;
		}

		return true;
	}

	public void enableWorld(String name) {

		List<String> worlds = pluginConfig.getGlobalSettings().getProhibitedWorlds().getWorld();

		worlds.remove(name);

		persist();
	}

	public void disableWorld(String name) {
		List<String> worlds = pluginConfig.getGlobalSettings().getProhibitedWorlds().getWorld();

		if (!worlds.contains(name)) {
			worlds.add(name);
		}

		persist();
	}

	public int getMaxImageWidth() {
		return pluginConfig.getGlobalSettings().getMaxImageWidth();
	}

	public int getMaxImageHeight() {
		return pluginConfig.getGlobalSettings().getMaxImageHeight();
	}
}
